package com.processmanager.sdk.model;

import com.processmanager.sdk.enums.ProcessStatus;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 进程信息模型
 * 
 * <p>包含进程的完整信息，包括：</p>
 * <ul>
 *   <li>进程ID和名称</li>
 *   <li>执行命令</li>
 *   <li>当前状态</li>
 *   <li>启动和结束时间</li>
 *   <li>实时日志</li>
 *   <li>错误信息</li>
 * </ul>
 * 
 * @author ProcessManager
 * @version 1.0.0
 * @since 2024-01-01
 */
public class ProcessInfo {
    
    /**
     * 进程唯一标识
     */
    @JsonProperty("processId")
    private String processId;
    
    /**
     * 进程名称
     */
    @JsonProperty("name")
    private String name;
    
    /**
     * 执行的命令
     */
    @JsonProperty("command")
    private String command;
    
    /**
     * 进程当前状态
     */
    @JsonProperty("status")
    private ProcessStatus status;
    
    /**
     * 进程启动时间
     */
    @JsonProperty("startTime")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime startTime;
    
    /**
     * 进程结束时间
     */
    @JsonProperty("endTime")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime endTime;
    
    /**
     * 进程日志列表（线程安全）
     */
    @JsonProperty("logs")
    private List<ProcessLog> logs;
    
    /**
     * 错误信息
     */
    @JsonProperty("errorMessage")
    private String errorMessage;
    
    /**
     * 退出码
     */
    @JsonProperty("exitCode")
    private Integer exitCode;
    
    /**
     * 默认构造函数
     */
    public ProcessInfo() {
        this.logs = new CopyOnWriteArrayList<>();
        this.status = ProcessStatus.STARTING;
        this.startTime = LocalDateTime.now();
    }
    
    /**
     * 带参数的构造函数
     * 
     * @param processId 进程ID
     * @param name 进程名称
     * @param command 执行命令
     */
    public ProcessInfo(String processId, String name, String command) {
        this();
        this.processId = processId;
        this.name = name;
        this.command = command;
    }
    
    // Getters and Setters
    
    public String getProcessId() {
        return processId;
    }
    
    public void setProcessId(String processId) {
        this.processId = processId;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getCommand() {
        return command;
    }
    
    public void setCommand(String command) {
        this.command = command;
    }
    
    public ProcessStatus getStatus() {
        return status;
    }
    
    public void setStatus(ProcessStatus status) {
        this.status = status;
    }
    
    public LocalDateTime getStartTime() {
        return startTime;
    }
    
    public void setStartTime(LocalDateTime startTime) {
        this.startTime = startTime;
    }
    
    public LocalDateTime getEndTime() {
        return endTime;
    }
    
    public void setEndTime(LocalDateTime endTime) {
        this.endTime = endTime;
    }
    
    public List<ProcessLog> getLogs() {
        return logs;
    }
    
    public void setLogs(List<ProcessLog> logs) {
        this.logs = logs;
    }
    
    public String getErrorMessage() {
        return errorMessage;
    }
    
    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }
    
    public Integer getExitCode() {
        return exitCode;
    }
    
    public void setExitCode(Integer exitCode) {
        this.exitCode = exitCode;
    }
    
    /**
     * 添加日志条目
     * 
     * @param log 日志条目
     */
    public void addLog(ProcessLog log) {
        this.logs.add(log);
    }
    
    /**
     * 获取运行时长（秒）
     * 
     * @return 运行时长，如果进程未结束则返回当前运行时长
     */
    public long getDurationSeconds() {
        LocalDateTime endTime = this.endTime != null ? this.endTime : LocalDateTime.now();
        return java.time.Duration.between(this.startTime, endTime).getSeconds();
    }
    
    @Override
    public String toString() {
        return "ProcessInfo{" +
                "processId='" + processId + '\'' +
                ", name='" + name + '\'' +
                ", status=" + status +
                ", startTime=" + startTime +
                '}';
    }
} 